# coding: utf-8

from flask import (
    render_template, redirect, url_for, flash, request, current_app
)
from flask_login import login_required
from sqlalchemy import or_, and_

from app.op.models import User
from .constant import VirtualNumberValid
from .. import db
from app.constant import Choice

from . import axb_bp
from .models import (
    VirtualNumber, CallOrderForLT, CallOrderForYD,
    SmsOrder, QueryCallNumberRecord, QuerySmsNumberRecord
)
from .call_order_forms import (
    SearchCallOrderForm, SearchMessageForm,
    SearchCallNumberRecord, SearchSmsNumberRecord,
    SearchNumberRelationForm, AddVirtualNumberForm,
    DetailVirtualNumberForm
)


@axb_bp.route('/virtual_numbers', methods=['GET', 'POST'])
def virtual_number_list():

    form = SearchNumberRelationForm(formdata=request.form or request.args)
    query = VirtualNumber.query

    url_kwargs = {}
    if form.validate():
        query_kwargs, url_kwargs = form.generate_kwargs()
        query = VirtualNumber.generate_list_query_condition(
            args=query_kwargs,
            query=query
        )

        if form.for_axb.data:
            query = query.filter(
                VirtualNumber.tel_b != ''
            )

    page = request.args.get('page', 1, type=int)
    pagination = query.order_by(VirtualNumber.id.desc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    items = pagination.items

    return render_template(
        'call_order/virtual_number_list.html',
        form=form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
    )


def get_distinct_outer_user(cls):
    """
    add by zhouhl 2017-10-19
    根据传入的话单类，查询外部工程商，返回一个集合
    因为移动的虚拟号先使用，所以先查移动的外部工程商，再查联通的外部工程商。
    """
    records = cls.get_list_by_args(
        outer_user=Choice.YES.value
    )
    result_set = {i.caller for i in records}
    return result_set


def get_distinct_outer_user_number():
    """
    add by zhouhl 2017-10-19
    返回移动和联通虚拟号捕获的外部工程商数目
    """
    outer_user_yd = get_distinct_outer_user(CallOrderForYD)
    outer_user_lt = get_distinct_outer_user(CallOrderForLT)
    outer_user_num_yd = len(outer_user_yd)
    outer_user_num_lt = len(outer_user_lt - outer_user_yd)
    return outer_user_num_yd, outer_user_num_lt


@axb_bp.route('/call_order_lt', methods=['GET', 'POST'])
@login_required
def call_order_lt():
    form = SearchCallOrderForm(formdata=request.form or request.args)

    query = CallOrderForLT.query
    url_kwargs = {}
    if form.validate():
        _, url_kwargs = form.generate_kwargs()
        query = CallOrderForLT.generate_list_query_condition(
            args=url_kwargs,
            query=query
        )

    page = request.args.get('page', 1, type=int)
    pagination = query.order_by(CallOrderForLT.id.desc()).paginate(
        # page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        page, per_page=1000,
        error_out=False)
    items = pagination.items

    outer_user_num_yd, outer_user_num_lt = get_distinct_outer_user_number()

    return render_template(
        'call_order/call_order_lt.html',
        form=form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
        outer_user_num_yd=outer_user_num_yd,
        outer_user_num_lt=outer_user_num_lt,
    )


@axb_bp.route('/call_order_yd', methods=['GET', 'POST'])
@login_required
def call_order_yd():
    form = SearchCallOrderForm(formdata=request.form or request.args)

    query = CallOrderForYD.query
    url_kwargs = {}
    if form.validate():
        _, url_kwargs = form.generate_kwargs()
        query = CallOrderForYD.generate_list_query_condition(
            args=url_kwargs,
            query=query
        )

    page = request.args.get('page', 1, type=int)
    pagination = query.order_by(CallOrderForYD.id.desc()).paginate(
        # page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        page, per_page=1000,
        error_out=False)
    items = pagination.items

    outer_user_num_yd, outer_user_num_lt = get_distinct_outer_user_number()

    return render_template(
        'call_order/call_order_yd.html',
        form=form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
        outer_user_num_yd=outer_user_num_yd,
        outer_user_num_lt=outer_user_num_lt,
    )


@axb_bp.route('/lt_message_show', methods=['GET', 'POST'])
@login_required
def lt_message_show():
    form = SearchMessageForm(formdata=request.form or request.args)

    query = SmsOrder.query
    url_kwargs = {}
    if form.validate():
        _, url_kwargs = form.generate_kwargs()
        query = SmsOrder.generate_list_query_condition(
            args=url_kwargs,
            query=query
        )

    page = request.args.get('page', 1, type=int)
    pagination = query.order_by(SmsOrder.id.desc()).paginate(
        # page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        page, per_page=1000,
        error_out=False)
    items = pagination.items

    return render_template(
        'call_order/lt_message_show.html',
        form=form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
    )


@axb_bp.route('/demand/win_bid_audio/<demand_id>/<client_id>/<win_user_id>')
def win_bid_audio(demand_id, client_id, win_user_id):
    """
    alter by chenhj 2018-05-07 取消显示双向外呼录音(且之前的逻辑也有问题,会把该客户与其他中标工程商的录音给显示出来了, 因为分配了同一个虚拟号)
    alter by zhouhl 2018-03-05 增加因为双向外呼导致的录音显示不全的bug。因为双向外呼里面的主叫号码是七陌的固话号，所以只根据工程商手机号会造成录音丢失
    created by chenhj at 2017/11/30
    """
    win_user = User.get_by_id(win_user_id)
    client = User.get_by_id(client_id)

    # add by zhouhl 2018-03-05 根据工程商和客户的虚拟号，加上客户真实号码，从CallOrderForLT中查通话记录
    virtual_number_record = VirtualNumber.query.filter_by(
        tel_a=client.mobile,
        tel_b=win_user.mobile,
        demand_id=demand_id,
    ).order_by(
        VirtualNumber.id.desc()
    ).first()

    win_user_caller_data = CallOrderForLT.get_list_by_args(
        caller=win_user.mobile,
        called=client.mobile,
        caller_show=virtual_number_record.tel_x,
    ) if virtual_number_record else []
    client_caller_data = CallOrderForLT.get_list_by_args(
        caller=client.mobile,
        called=win_user.mobile,
        caller_show=virtual_number_record.tel_x,
    ) if virtual_number_record else []

    return render_template(
        'call_order/win_bid_audio.html',
        win_user_caller_data=win_user_caller_data,
        client_caller_data=client_caller_data
    )


@axb_bp.route('/query_call_number_record', methods=['GET', 'POST'])
@login_required
def query_call_number_record():
    form = SearchCallNumberRecord(formdata=request.form or request.args)

    query = QueryCallNumberRecord.query
    url_kwargs = {}
    if form.validate():
        query_kwargs, url_kwargs = form.generate_kwargs()
        if form.lt_called.data:
            query = query.filter(
                CallOrderForLT.called == form.lt_called.data
            ).join(
                CallOrderForLT, CallOrderForLT.recorder_id == QueryCallNumberRecord.recorder_id
            )

        query = QueryCallNumberRecord.generate_list_query_condition(
            args=query_kwargs,
            query=query
        )

    page = request.args.get('page', 1, type=int)
    pagination = query.paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    items = pagination.items

    return render_template(
        'call_order/query_call_number_record.html',
        form=form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
    )


@axb_bp.route('/query_sms_number_record', methods=['GET', 'POST'])
@login_required
def query_sms_number_record():
    form = SearchSmsNumberRecord(formdata=request.form or request.args)

    query = QuerySmsNumberRecord.query
    url_kwargs = {}
    if form.validate():
        query_kwargs, url_kwargs = form.generate_kwargs()
        query = QuerySmsNumberRecord.generate_list_query_condition(
            args=query_kwargs,
            query=query
        )

    page = request.args.get('page', 1, type=int)
    pagination = query.paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    items = pagination.items

    return render_template(
        'call_order/query_sms_number_records.html',
        form=form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
    )


@axb_bp.route('/add_virtual_number', methods=['GET', 'POST'])
@login_required
def add_virtual_number():
    """
    新增虚拟号绑定关系
    """
    form = AddVirtualNumberForm()
    tel_a = form.tel_a.data
    tel_b = form.tel_b.data
    tel_x = form.tel_x.data

    if form.validate_on_submit():

        # 虚拟号不能新增重复的
        is_axb = VirtualNumber.query.filter(
            or_(
                and_(VirtualNumber.tel_a == tel_a, VirtualNumber.tel_b == tel_b),
                and_(VirtualNumber.tel_a == tel_b, VirtualNumber.tel_b == tel_a)
            ),
            VirtualNumber.tel_x == tel_x,
            VirtualNumber.valid == VirtualNumberValid.VALID.value
        ).first()

        # 已经绑定过虚拟号的号码不能通过同一个虚拟号绑定其他号码
        bind_axb = VirtualNumber.query.filter(
            or_(
                VirtualNumber.tel_a.in_([tel_a, tel_b]),
                VirtualNumber.tel_b.in_([tel_a, tel_b]),
                ),
            VirtualNumber.tel_x == tel_x,
            VirtualNumber.valid == VirtualNumberValid.VALID.value
        ).first()

        # 已经存在相同的tel_a绑定了这个虚拟号
        is_axn = VirtualNumber.query.filter(
            VirtualNumber.tel_a == tel_a,
            VirtualNumber.tel_x == tel_x,
            VirtualNumber.valid == VirtualNumberValid.VALID.value
        ).first()

        # 已经绑定过axn的虚拟号不能够被重复使用
        bind_axn = VirtualNumber.query.filter(
            VirtualNumber.tel_b == '',
            VirtualNumber.tel_x == tel_x,
            VirtualNumber.valid == VirtualNumberValid.VALID.value
        ).first()

        if tel_b:
            if is_axb:
                flash('axb绑定关系已存在，请勿重复添加')
                return render_template(
                    "/call_order/add_virtual_number.html",
                    form=form,
                )
            elif bind_axb:
                flash('已经绑定了虚拟号，请勿重复使用虚拟号')
                return render_template(
                    "/call_order/add_virtual_number.html",
                    form=form,
                )

        else:
            if is_axn:
                flash('已存在绑定关系，请勿重复添加')
                return render_template(
                    "/call_order/add_virtual_number.html",
                    form=form,
                )
            elif bind_axn:
                flash('虚拟号已经被使用')
                return render_template(
                    "/call_order/add_virtual_number.html",
                    form=form,
                )

        add_virtual = VirtualNumber()
        form.populate_obj(add_virtual)

        db.session.add(add_virtual)
        db.session.flush()

        flash('新增虚拟号绑定关系成功')
        return redirect(url_for('axb_bp.virtual_number_list'))
    else:
        if form.errors:
            flash('表单数据有误，请检查')
            print(form.errors)

    return render_template(
        "/call_order/add_virtual_number.html",
        form=form,
    )


@axb_bp.route('/virtual_number/<int:id>', methods=['GET'])
@login_required
def virtual_number_info(id):
    virtual_number = VirtualNumber.query.get_or_404(id)
    form = DetailVirtualNumberForm(obj=virtual_number)

    return render_template(
        'call_order/virtual_number_info.html',
        virtual_number=virtual_number,
        form=form,
    )


@axb_bp.route('/edit_virtual_number/<int:id>', methods=['POST'])
@login_required
def edit_virtual_number(id):
    virtual_number = VirtualNumber.query.get_or_404(id)
    form = DetailVirtualNumberForm()

    if form.validate_on_submit():

        if form.valid.data == VirtualNumberValid.INVALID.value:
            virtual_number.valid = form.valid.data
        else:
            flash('不可更改为有效')
            return redirect(url_for('axb_bp.virtual_number_info', id=virtual_number.id))

        flash('修改成功')
        return redirect(url_for('axb_bp.virtual_number_list'))
    else:
        flash('编辑出错，请检查数据。')
        return redirect(url_for('axb_bp.virtual_number_info', id=virtual_number.id))
